package com.justin.demo;

import com.justin.demo.utils.LogUtils;
import com.justin.demo.utils.MyThreadUtils;

public class MyDemo002 {

    /**
     *  守护线程问题
     *  线程分为守护线程和用户线程两种：
     *      守护线程为： 守护线程是所有非守护线程的保姆，当所有非守护线程执行完成或退出了，即使还有守护线程在运行，JVM也会直接退出。
     *      用户线程： 用户线程，只要有一个线程在运行，JVM就不会退出
     *
     *
     *  放开代码【001】可以发现，当线程设置为守护线程后，主线程一旦执行完毕，程序退出，守护线程也随着立即终止，就不会打印出守护线程执行结束的日志。
     *  放开代码【002】可以发现，虽然主线程已经执行完毕，但创建的非守护线程还在运行，直到运行结束。
     *
     *  ps:
     *      1、setDaemon方法中通过isAlive判断线程是否已启动，已启动状态下不允许修改，抛出IllegalThreadStateException异常。
     *      2、如果没有显示调用setDaemon方法进行设置，线程的模式是取决于父线程是否为守护线程，也就是创建此线程所在的线程。
     *          （1）、如果父线程是守护线程，创建的线程默认是守护线程；
     *          （2）、如果父线程是用户线程，创建的线程默认是用户线程。
     *
     *  测试结果见控制台
     */
    public static void main(String[] args) throws Exception {
        // 修改主线程名
        Thread.currentThread().setName("我是主线程");
        LogUtils.info("当前主线程[{}] 执行开始", Thread.currentThread().getName());

        /** 代码【001】开始 */
//        Thread t001 = new Thread(() -> {
//            Thread.currentThread().setName("守护线程");
//            LogUtils.info("当前线程[{}] 执行开始", Thread.currentThread().getName());
//            try {
//                Thread.sleep(5000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            LogUtils.info("当前线程[{}] 执行结束", Thread.currentThread().getName());
//        });
//        //	设置为守护线程
//        t001.setDaemon(true);
//        t001.start();
        /** 代码【001】结束 */
        /** 代码【002】开始 */
//        Thread t002 = new Thread(() -> {
//            Thread.currentThread().setName("用户线程");
//            LogUtils.info("当前线程[{}] 执行开始", Thread.currentThread().getName());
//            try {
//                Thread.sleep(5000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            LogUtils.info("当前线程[{}] 执行结束", Thread.currentThread().getName());
//        });
//        t002.start();
        /** 代码【002】结束 */

        Thread.sleep(1000);
        LogUtils.info("当前主线程[{}] 执行结束", Thread.currentThread().getName());

    }

}
